package main

import "fmt"

// 定义中介者接口
type Mediator interface {
	Register(colleague Colleague)
	Notify(colleague Colleague, message string)
}

// 定义同事接口
type Colleague interface {
	SetMediator(mediator Mediator)
	Request(message string)
	Receive(message string)
}

// 具体同事类
type AirCraft struct {
	name     string
	mediator Mediator
}

func (a *AirCraft) SetMediator(mediator Mediator) {
	a.mediator = mediator
}

func (a *AirCraft) Request(message string) {
	fmt.Println("飞机 :", a.name, " 发送请求: ", message)
	a.mediator.Notify(a, message)
}

func (a *AirCraft) Receive(message string) {
	fmt.Println("飞机 :", a.name, " 接收到请求: ", message)
}

type Runway struct {
	isOccupied bool
	name       string
	mediator   Mediator
}

func (r *Runway) SetMediator(mediator Mediator) {
	r.mediator = mediator
}

func (r *Runway) Request(message string) {
	fmt.Println("跑道 :", r.name, " 发送请求: ", message)
	r.mediator.Notify(r, message)
}
func (r *Runway) Receive(message string) {
	fmt.Println("跑道 :", r.name, " 接收到请求: ", message)
}

// 具体中介者类
type ControlTower struct {
	Colleagues []Colleague
	AirCrafts  []Colleague
	Runways    []Colleague
}

func (c *ControlTower) Register(colleague Colleague) {
	c.Colleagues = append(c.Colleagues, colleague)
	if _, ok := colleague.(*AirCraft); ok {
		c.AirCrafts = append(c.AirCrafts, colleague)
	}
	if _, ok := colleague.(*Runway); ok {
		c.Runways = append(c.Runways, colleague)
	}
}
func (c *ControlTower) Notify(colleague Colleague, message string) {
	switch message {
	case "请求降落":
		for _, runway := range c.Runways {
			if !runway.(*Runway).isOccupied {
				runway.Receive(fmt.Sprintf("请准备跑道让%s降落", colleague.(*AirCraft).name))
				runway.(*Runway).isOccupied = true
				colleague.Receive(fmt.Sprintf("请求成功，请于%s降落", runway.(*Runway).name))
				return
			}
		}
		colleague.Receive("当前无跑道，请稍等")
	case "起飞完成":
		colleague.(*Runway).isOccupied = false
		colleague.Receive("辛苦了，塔台已收到")
		return
	case "天气预警":
		colleague.Receive("塔台收到天气预警")
		for _, colleague := range c.Colleagues {
			colleague.Receive("通知：请注意恶劣天气")
		}
	}
}

func main() {
	controlTower := &ControlTower{}
	a1 := &AirCraft{name: "A1"}
	a2 := &AirCraft{name: "A2"}
	a3 := &AirCraft{name: "A3"}
	r1 := &Runway{name: "R1"}
	r2 := &Runway{name: "R2"}
	controlTower.Register(a1)
	controlTower.Register(a2)
	controlTower.Register(a3)
	controlTower.Register(r1)
	controlTower.Register(r2)
	a1.SetMediator(controlTower)
	a2.SetMediator(controlTower)
	a3.SetMediator(controlTower)
	r1.SetMediator(controlTower)
	r2.SetMediator(controlTower)
	a1.Request("请求降落")
	a2.Request("请求降落")
	a3.Request("请求降落")
	r1.Request("起飞完成")
	a3.Request("请求降落")
	r2.Request("天气预警")
}
